<!--
编辑楼层
-->

<template>
  <a-drawer
    :title="title"
    :visible="visible"
    :destroyOnClose="true"
    :width="$store.getters.isMobile ? 350 : 450"
    :body-style="{ paddingBottom: '80px' }"
    @close="closeModal"
  >
    <a-form layout="vertical">
      <a-form-item v-bind="validateInfos.layer_number">
        <template #label>
          <span>楼层数字编号</span>
          <text-tip
            :tips="[
              '用于楼层列表进行排序，以及未来智能设备等第三方对接使用。地下室使用负数表示',
            ]"
          />
        </template>
        <a-input-number
          class="w-100p"
          placeholder="请输入楼层数字编号"
          v-model:value="modelRef.layer_number"
        />
      </a-form-item>
      <a-form-item label="楼层名称" v-bind="validateInfos.layer_name">
        <a-input
          placeholder="请输入楼层名称"
          v-model:value="modelRef.layer_name"
        />
      </a-form-item>
      <a-form-item label="楼层2D平面图模型" v-bind="validateInfos.two_dimensional">
        <a-button type="primary" @click="goEdit2D" :loading="twoDimensionalLoading">
          去编辑
        </a-button>
      </a-form-item>
      <a-form-item v-bind="validateInfos.three_dimensional_file">
        <template #label>
          <span>楼层3D可视化模型</span>
          <text-tip
            :tips="[
              '仅支持FBX格式文件',
              '点击去编辑按钮进入编辑3D模型， 点击其他区域可以重新上传替换文件',
            ]"
          />
        </template>
        <a-upload-dragger
          v-model:fileList="fileList"
          name="file"
          :multiple="false"
          :action="$utils.fileAction"
          :headers="{ 'org-token': $store.getters.token }"
          :showUploadList="false"
          @change="handleUploadChange"
          accept=".fbx"
          :data="{ dir: 'org_layer_fbx' }"
        >
          <template v-if="fileList.length">
            <p class="ant-upload-drag-icon">
              <FileTextOutlined />
            </p>
            <p class="ant-upload-text">
              {{ fileList[0].name }}
            </p>
            <!-- <a-button
              type="primary"
              v-if="content.three_dimensional_file && fileList.length"
              @click.stop="handleLayer3DEdit"
              >去编辑</a-button
            > -->
          </template>
          <template v-else>
            <p class="ant-upload-drag-icon">
              <InboxOutlined />
            </p>
            <p class="ant-upload-text">
              拖拽文件至虚线款内或点击此区域上传文件
            </p>
            <p class="ant-upload-hint">请上传fbx格式的3D可视化模型</p>
          </template>
        </a-upload-dragger>
      </a-form-item>
    </a-form>
    <div class="drawer-footer">
      <a-space>
        <a-button @click.prevent="closeModal">取消</a-button>
        <a-button type="primary" @click.prevent="onSubmit">保存</a-button>
      </a-space>
    </div>

    <Layer2DEdit
      :visible="twoDimensionalVisible"
      :roomList="roomList || []"
      :editInfo="modelRef.two_dimensional"
      @handleClose="handleClose"
      @handleOK="handleOK"
    />
  </a-drawer>
</template>

<script>
import {
  computed,
  defineComponent,
  reactive,
  ref,
  toRaw,
  toRefs,
  watch,
} from "vue";
import { Form, message } from "ant-design-vue";
import request from "../../../../common/utils/request";
import {FileTextOutlined, InboxOutlined, PlusOutlined} from "@ant-design/icons-vue";
import { TextTip } from "bl-common-vue3";
const useForm = Form.useForm;
import Layer2DEdit from "@/views/village/BuildingManage/modules/Layer2DEdit.vue";
import _ from "lodash";
import {uuid} from "vue-uuid";

export default defineComponent({
  name: "EditLayer",
  components: {
    PlusOutlined,
    FileTextOutlined,
    InboxOutlined,
    TextTip,
    Layer2DEdit,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    content: {
      type: Object,
      default: () => ({}),
    },
  },
  setup(props, context) {
    const title = computed(() => {
      return props.content.id ? "编辑楼层" : "添加楼层";
    });

    const state = reactive({
      fileList: [],
      numberDisabled: false,
      twoDimensionalVisible: false,
      roomList: [],
      twoDimensionalLoading: false,
    });

    const closeModal = () => {
      context.emit("cancel");
    };

    const modelRef = reactive({
      layer_number: "",
      layer_name: "",
      three_dimensional_file: "",
      two_dimensional: {},
    });

    const rulesRef = reactive({
      layer_number: [{ required: true, message: "必填" }],
      layer_name: [{ required: true, message: "必填" }],
    });

    const { resetFields, validate, validateInfos } = useForm(
      modelRef,
      rulesRef
    );

    let messageKey = "upload";
    const handleUploadChange = (info) => {
      let resFileList = [...info.fileList];
      resFileList = resFileList.slice(-1);
      state.fileList = resFileList;
      const result = state.fileList[0];
      if (result.status == "uploading") {
        message.loading({
          content: "文件上传中",
          key: messageKey,
          duration: 0,
        });
      } else if (result.status == "done" && result.response) {
        if (result.response.code == 1000) {
          modelRef.three_dimensional_file = result.response.data.fileUrl;
          message.success({
            content: "上传成功!",
            key: messageKey,
            duration: 2,
          });
        } else {
          message.error({
            content: result.response.msg || "上传失败!",
            key: messageKey,
            duration: 2,
          });
        }
      } else if (result.status == "error") {
        message.error({ content: "上传失败!", key: messageKey, duration: 2 });
      }
    };

    const onSubmit = () => {
      validate().then(() => {
        const { content } = props;
        console.log("content", content);
        let method = "post";
        const params = {
          ...modelRef,
          build_id: content.buildId || content.build_id,
          village_id: content.villageId || content.village_id,
          needMsg: true,
        };
        if (content.id) {
          method = "put";
          params.id = content.id;
        }
        request[method]("/village", "/project/layer", params).then((res) => {
          message.success(res.msg || "保存成功！");
          context.emit("success");
        });
      });
    };

    const parseRatio = (number, decimal = 2) => {
      return (Math.floor(number * 100) / 100).toFixed(decimal);
    };

    // 设置空房间比例 endIndex不包含
    const setEmptyRoomRatio = (list, startIndex = 0, endIndex) => {
      endIndex = endIndex || list.length;
      let length = endIndex - startIndex;
      if (length < 10) {
        for (let i = startIndex; i < endIndex; i++) {
          list[i].areaRatio = parseRatio(100 / length);
        }
      } else {
        const remainder = length % 10;
        const integer = length / 10;
        for (let i = integer * 10; i < remainder; i++) {
          list[i].areaRatio = parseRatio(100 / remainder);
        }
      }
    };

    // 回溯处理
    const setBeforeArea = (list, lastIndex, currentIndex) => {
      if (currentIndex == 0) {
        list[0].areaRatio = 100;
        return;
      }
      const hasAreaRoom = [];
      let total = 0;
      for (let i = lastIndex; i < currentIndex; i++) {
        const item = list[i];
        if (Number(item.build_area)) {
          hasAreaRoom.push(item);
          total = Number(total) + Number(item.areaRatio);
        }
      }
      if (hasAreaRoom.length) {
        const emptyNum = currentIndex - lastIndex - hasAreaRoom.length;
        let remainTotal = 100 - emptyNum * 10; // 除去空房间剩余总空间
        for (let item of hasAreaRoom) {
          item.areaRatio = parseRatio(
            (Number(item.areaRatio) / total) * remainTotal
          );
        }
      } else {
        setEmptyRoomRatio(list, lastIndex, currentIndex);
      }
    };

    // 整理房间的最终比例
    const handleRoomFinalArea = (list) => {
      let total = 0;
      let lastIndex = 0;
      for (let i = 0; i < list.length; i++) {
        let item = list[i];
        total = total + Number(item.areaRatio);
        if (i == list.length - 1) {
          if (total >= 100) {
            // 只剩最后一个会折行
            setBeforeArea(list, lastIndex, i);
            setBeforeArea(list, i, i + 1);
          } else {
            // 最后一行铺不满的情况
            setBeforeArea(list, lastIndex, i + 1);
          }
        } else if (total >= 100) {
          // 面积已满一行
          setBeforeArea(list, lastIndex, i);
          total = Number(item.areaRatio);
          lastIndex = i;
        }
      }
    };

    const getEditInfo = () => {
      const { content } = props;
      if (content.id) {
        state.twoDimensionalLoading = true;
        request
          .get("/village", "/profile/profile", {
            villageId: content.villageId || content.village_id,
            buildId: content.buildId || content.build_id,
            layerId: content.id
          }).then((res) => {
          if (res.list && res.list.length > 0) {
            res.list.forEach((layer) => {
              let totalArea = Number(layer.build_area);
              if (totalArea) {
                //  有房间含有面积
                const emptyRoom = layer.room_list.filter(
                  (item) => !item.build_area || item.build_area == 0
                );
                const emptyRoomArea = emptyRoom.length ? totalArea * 10 * 0.01 : 0;
                layer.room_list.forEach((room, roomIndex) => {
                  if (Number(room.build_area)) {
                    // 计算比例
                    room.areaRatio = parseRatio(
                      ((Number(room.build_area) + emptyRoomArea) / totalArea) * 100
                    );
                    if (Number(room.areaRatio) > 100) {
                      room.areaRatio = 100;
                    }
                    if (Number(room.areaRatio) < 10) {
                      room.areaRatio = 10;
                    }
                  } else {
                    // 没有面积仍然算10%
                    room.areaRatio = 10;
                  }
                });
                handleRoomFinalArea(layer.room_list);
              } else {
                // 所有房间都是空的，超过10个房间按10%，不超过10个房间一行均分
                setEmptyRoomRatio(layer.room_list);
              }
            });
            state.roomList = res.list[0]?.room_list || [];
          }
          state.twoDimensionalLoading = false;
        })
      }
      if (content.id) {
        state.numberDisabled = true;
        modelRef.layer_number = content.layer_number;
        modelRef.layer_name = content.layer_name;
        if (content.three_dimensional_file) {
          modelRef.three_dimensional_file = content.three_dimensional_file;
          state.fileList = [
            {
              uid: "1",
              name: `${content.layer_name}_3D可视化模型.fbx`,
              status: "done",
              url: content.three_dimensional_file,
            },
          ];
        }
        if (content?.two_dimensional && !Array.isArray(content?.two_dimensional)) {
          modelRef.two_dimensional = content.two_dimensional;
        }
      } else {
        state.numberDisabled = false;
      }
    };

    const handleLayer3DEdit = () => {
      const { content } = props;
      window.open(
        `${location.origin + location.pathname}#/main/3d/layer?layerId=${
          content.id
        }&buildId=${content.buildId}&villageId=${content.villageId}&type=edit`
      );
    };

    const goEdit2D = () => {
      state.twoDimensionalVisible = true;
    };

    const handleClose = () => {
      state.twoDimensionalVisible = false;
    };

    const handleOK = (val) => {
      modelRef.two_dimensional = _.cloneDeep(val);
      handleClose();
    };

    const reset = () => {
      state.fileList = [];
      state.twoDimensionalVisible = false;
      state.roomList = [];
      state.twoDimensionalLoading = false;
    }

    watch(
      () => props.visible,
      (val) => {
        if (val) {
          getEditInfo();
        } else {
          resetFields();
          reset();
        }
      }
    );
    return {
      ...toRefs(state),
      title,
      modelRef,
      validateInfos,
      handleUploadChange,
      closeModal,
      resetFields,
      onSubmit,
      handleLayer3DEdit,
      goEdit2D,
      handleClose,
      handleOK,
    };
  },
});
</script>

<style lang="less" scoped>
.ant-upload-text {
  font-size: 14px !important;
}
</style>
